/*
 * Copyright (C) 2020 唐家林
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package db

import (
	"database/sql"
	"errors"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
	"github.com/sudot/yapi-tools/internal"
	"github.com/sudot/yapi-tools/internal/assets"
	"github.com/sudot/yapi-tools/internal/logger"
	"os"
	"path/filepath"
)

var DB *sql.DB

func init() {
	dbPath, _ := filepath.Abs(filepath.Join(internal.WorkPath, "data.db"))
	logger.Infof("数据文件路径：%s", dbPath)
	_, err := os.Stat(dbPath)
	if err != nil && os.IsNotExist(err) {
		_, err := os.Create(dbPath)
		if err != nil {
			panic(fmt.Sprintf("数据库创建失败:%s %s", dbPath, err))
		}
	}
	DB = open(dbPath)
	if !CheckTableExist("interface") {
		ddlBytes, _ := assets.Asset("assets/db/ddl.sql")
		_, err = DB.Exec(string(ddlBytes))
		if err != nil {
			panic(fmt.Sprintf("数据库初始化失败 %s %s", dbPath, err))
		}
	}
}

func open(dbName string) *sql.DB {
	db, err := sql.Open("sqlite3", dbName)
	// 运行后程序就退出了,所以无需关闭db
	if err != nil {
		panic(errors.New("数据库连接失败:" + err.Error()))
	}
	return db
}

func CheckTableExist(tableName string) bool {
	b := false
	err := DB.QueryRow("SELECT COUNT(1) FROM sqlite_master WHERE type = 'table' and name = ?", tableName).Scan(&b)
	if err != nil {
		panic(errors.New(fmt.Sprintf("表检测失败。检测表：%s", tableName)))
	}
	return b
}

func CheckColumnExist(tableName string, columnName string) bool {
	rows, err := DB.Query("PRAGMA table_info(?)", tableName)
	if err != nil {
		panic(errors.New(fmt.Sprintf("表字段检测-表信息查询失败。检测表：%s，字段：%s", tableName, columnName)))
	}
	var name string
	for rows.Next() {
		err := rows.Scan(&name)
		if err != nil {
			panic(errors.New(fmt.Sprintf("表字段检测-表信息获取失败。检测表：%s，字段：%s", tableName, columnName)))
		}
		if name == columnName {
			return true
		}
	}
	return false
}
